package com.hzeng.util;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class MyQueue<T> implements Runnable{
	private boolean started = false;
    private Queue<T> storage = new LinkedList<T>();
    private int size = 2;
    private long interval = 2000l;
    private List<Long> pids = null;
    
    private MyTimeSeriesChart myChart = null;
    private ProgramRecorder recorder = null;

	public MyQueue(){
    	
    }
    
    public MyQueue(int size){
    	this.size = size;
    }
    
    public MyQueue(int size,long interval){
    	this.size = size;
    	this.interval = interval;
    }
    
    public ProgramRecorder getRecorder() {
		return recorder;
	}

	public void setRecorder(ProgramRecorder recorder) {
		this.recorder = recorder;
	}
	
	public void addRecorderListener(ProgramRecorder recorder) {
		this.recorder = recorder;
	}
	
	public void removeRecorderLister() {
		this.recorder = null;
	}

	public void addChartListener(MyTimeSeriesChart myChart) {
    	this.myChart = myChart;
    }
    public void removeChartListener() {
    	this.myChart = null;
    }

    public List<Long> getPids() {
		return pids;
	}

	public void setPids(List<Long> pids) {
		this.pids = pids;
	}

	public boolean isStarted() {
		return started;
	}

	public void setStarted(boolean started) {
		this.started = started;
	}

    public int getSize() {
		return size;
	}

	public void setSize(int size) {
		this.size = size;
	}

	public long getInterval() {
		return interval;
	}

	public void setInterval(long interval) {
		this.interval = interval;
	}
	
	//add node
    @SuppressWarnings("unchecked")
	public void offer(T v) {
    	int s = storage.size();
    	//set queue with static width
    	if (s < this.size) {
			
		}else {
			storage.poll();
		}
        storage.offer(v);
        
        //calculate IO rate
        if (storage.size() == 2) {
			T firstT = storage.peek();
			ProgramMonitor.calculteOIRate((List<Program>)firstT, (List<Program>)v);
			
			//notify chart to update UI
			if (myChart != null) {
				myChart.updateChartData((List<Program>)firstT);
			}
			//notify file recorder to update data
			if (recorder != null) {
				recorder.recordDataInFile((List<Program>)firstT);
			}
		}
    }
    
    public void size() {
    	storage.size();
    }

    //get the first node in queue,but not delete it in queue
    public T peek() {
        return storage.peek();
    }

    //get the first node in queue,but not delete it in queue
    //if queue is empty,throw a exception
    public T element() {
        return storage.element();
    }

    //get and remove the first node in queue
    public T poll() {
        return storage.poll();
    }

	//get and remove the first node in queue
	//if queue is empty,throw a exception
    public T remove() {
        return storage.remove();
    }

    //check queue is empty or not
    public boolean empty() {
        return storage.isEmpty();
    }

    public String toString() {
        return storage.toString();
    }
    
    public static void main(String[] args) {
        MyQueue<List<Program>> myQueue = new MyQueue<List<Program>>();
        List<Long> pids = new ArrayList<Long>();
        pids.add(11592l);
        myQueue.setPids(pids);
        myQueue.setStarted(true);
        Thread thread = new Thread(myQueue);
		thread.start();
    }

	@SuppressWarnings("unchecked")
	@Override
	public void run() {
		ProgramMonitor pm = ProgramMonitor.getInstance();
		while (started) {
			List<Program> allPrograms = new ArrayList<Program>();
			Program sys = pm.recordSystemInfo();
			allPrograms.add(sys);
			if (pids != null && pids.size() > 0) {
				pm.setPids(pids);
				List<Program> programs = pm.getOneDataForAllPrograms();
				allPrograms.addAll(programs);
			}
			
			offer((T) allPrograms);
			try {
				Thread.sleep(interval);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
	}
}